package com.beiding.render;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

class TemplateCreator {


    static TemplateImpl create(String text, List<Pair> pairs, ULabel uBlock, ULabel uRender, String coordinate, RenderTime renderTime, Map<String, TemplateImpl> innerTpMap) {

        //创建一个模板
        TemplateImpl template = new TemplateImpl();

        template.setCoordinate(coordinate);

      //  Map<String, TemplateImpl> innerTpMap = new HashMap<>();

        //可以委托
        //template.setRenderTime(renderTime.copyFor(innerTpMap));

        template.setRenderTime(renderTime);

        //文本替换占位符
        text = uBlock.replaceHolder(text, pairs);

        //解析渲染表达式
        List<Pair> renders = uRender.parsePairs(text);

        //渲染表达式替换占位符
        text = uRender.replaceHolder(text, renders);

        //文本
        template.setText(text);

        //所有render
        template.setRenders(uRender.toLabel(renders, "render"));

        //有层级的分析所有Block
        template.setBlocks(uBlock.toLabel(pairs, (pair, label) -> {
            if (pair.hierarchy == 0) {
                label.template = create(pair.body, pair.toRootInners, uBlock, uRender, coordinate, template.getRenderTime(),innerTpMap);
                return true;
            }
            return false;
        }, "block"));


        //TODO 内部模板只有根节点能具备
        template.getBlocks().removeIf(t -> {
            String tp = t.commands.get("tp");

            if (tp != null) {
                tp = tp.trim();
                if (!tp.equals("")) {


                    if (innerTpMap.containsKey(tp)) {
                        throw new RuntimeException("重复的内置模板:" + tp);
                    }

                    //内部被声明为模板的元素将被提取为一个元素
                    template.setText(template.getText().replace(t.holder, ""));

                    TemplateImpl wrapInner = new TemplateImpl();

                    wrapInner.setRoot(t);

                    wrapInner.setBlocks(new ArrayList<>());

                    wrapInner.setRenders(new ArrayList<>());

                    wrapInner.setCoordinate(coordinate);
                    wrapInner.setText(t.holder);

                    //TODO 继承内置模板
                    wrapInner.setRenderTime(t.template.getRenderTime());

                    innerTpMap.put("$" + tp, wrapInner);

                    return true;
                }
            }
            return false;
        });


        return template;

    }


}
